gusucode.com > VC Outlook风格的数据库浏览器 > VC Outlook风格的数据库浏览器/gusucode/Outlook/FolderView.cpp

    //Download by http://www.NewXing.com
// FolderView.cpp : implementation file
//

#include "stdafx.h"
#include "mdbViewer.h"
#include "mdbViewerDoc.h"
#include "FolderView.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFolderView

IMPLEMENT_DYNCREATE(CFolderView, CTreeView)

CFolderView::CFolderView()
{
}

CFolderView::~CFolderView()
{
}

BEGIN_MESSAGE_MAP(CFolderView, CTreeView)
	//{{AFX_MSG_MAP(CFolderView)
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFolderView drawing

void CFolderView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CFolderView diagnostics

#ifdef _DEBUG
void CFolderView::AssertValid() const
{
	CTreeView::AssertValid();
}

void CFolderView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CFolderView message handlers

static CString csTreeItems[] =
{
	_T("Database - [Blank]")
};

static UINT nImages[] =
{
	IDI_ICON_DATABASE,
	IDI_ICON_TABLE,
	IDI_ICON_TABLEOPEN,
	IDI_ICON_RECORD	
};

CmdbViewerDoc* CFolderView::GetDocument()
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CmdbViewerDoc)));
	return (CmdbViewerDoc*)m_pDocument;
}

void CFolderView::OnInitialUpdate() 
{
	CTreeView::OnInitialUpdate();
	
	m_pTreeCtrl = &GetTreeCtrl();

	m_Font.CreatePointFont (85, _T("Tahoma"));
    m_pTreeCtrl->SetFont (&m_Font); 
	m_ImageList.Create (24, 24, true, 2, 1); // 16 by 16 is too small
	HICON hIcon;
	
	for (int i =0; i < 4; ++i) {
		hIcon= AfxGetApp()->LoadIcon (nImages[i]);
		m_ImageList.Add (hIcon);
	}

	m_pTreeCtrl->SetImageList( &m_ImageList, TVSIL_NORMAL );

	// add the parent items, with the first and second icons in
	// m_ImageList
	m_htiDatabase = m_pTreeCtrl->InsertItem( csTreeItems[0], 0, 0 );
	m_pTreeCtrl->SetItemState( m_htiDatabase, TVIS_BOLD, TVIS_BOLD );
	
}

BOOL CFolderView::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class
	cs.style |= TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT;
	return CTreeView::PreCreateWindow(cs);
}

// GetLastItem  - Gets last item in the branch
// Returns      - Last item
// hItem        - Node identifying the branch. NULL will 
//                return the last item in outine

HTREEITEM CFolderView::GetLastItem( HTREEITEM hItem )
{
        // Last child of the last child of the last child ...
        HTREEITEM htiNext;

        if( hItem == NULL ){
                // Get the last item at the top level
                htiNext = m_pTreeCtrl->GetRootItem();
                while( htiNext ){
                        hItem = htiNext;
                        htiNext = m_pTreeCtrl->GetNextSiblingItem( htiNext );
                }
        }

        while( m_pTreeCtrl->ItemHasChildren( hItem ) ){
                htiNext = m_pTreeCtrl->GetChildItem( hItem );
                while( htiNext ){
                        hItem = htiNext;
                        htiNext = m_pTreeCtrl->GetNextSiblingItem( htiNext );
                }
        }

        return hItem;
}

// GetNextItem  - Get next item as if outline was completely expanded
// Returns      - The item immediately below the reference item
// hItem        - The reference item
HTREEITEM CFolderView::GetNextItem( HTREEITEM hItem )
{
        HTREEITEM       hti;

        if( m_pTreeCtrl->ItemHasChildren( hItem ) )
                return m_pTreeCtrl->GetChildItem( hItem );           // return first child
        else{
                // return next sibling item
                // Go up the tree to find a parent's sibling if needed.
                while( (hti = m_pTreeCtrl->GetNextSiblingItem( hItem )) == NULL ){
                        if( (hItem = m_pTreeCtrl->GetParentItem( hItem ) ) == NULL )
                                return NULL;
                }
        }
        return hti;
}

// GetNextItem  - Get previous item as if outline was completely expanded
// Returns              - The item immediately above the reference item
// hItem                - The reference item
HTREEITEM CFolderView::GetPrevItem( HTREEITEM hItem )
{
        HTREEITEM       hti;

        hti = m_pTreeCtrl->GetPrevSiblingItem(hItem);
        if( hti == NULL )
                hti = m_pTreeCtrl->GetParentItem(hItem);
        else
                hti = GetLastItem(hti);
        return hti;
}

// FindItem		- Finds an item that contains the search string
// Returns		- Handle to the item or NULL
// str			- String to search for
// bCaseSensitive	- Should the search be case sensitive
// bDownDir		- Search direction - TRUE for down
// bWholeWord		- True if search should match whole words
// hItem		- Item to start searching from. NULL for
//			- currently selected item
HTREEITEM CFolderView::FindItem(CString &str, 
				BOOL bCaseSensitive /*= FALSE*/, 
				BOOL bDownDir /*= TRUE*/, 
				BOOL bWholeWord /*= FALSE*/, 
				HTREEITEM hItem /*= NULL*/)
{
	int lenSearchStr = str.GetLength();
	if( lenSearchStr == 0 ) return NULL;

	HTREEITEM htiSel = hItem ? hItem : m_pTreeCtrl->GetSelectedItem();
	HTREEITEM htiCur = bDownDir ?GetNextItem( htiSel ) : GetPrevItem( htiSel );
	CString sSearch = str;

	if( htiCur == NULL )
	{
		if( bDownDir )  htiCur = m_pTreeCtrl->GetRootItem();
		else htiCur = GetLastItem( NULL );
	}

	if( !bCaseSensitive )
		sSearch.MakeLower();

	while( htiCur && htiCur != htiSel )
	{
		CString sItemText = m_pTreeCtrl->GetItemText( htiCur );
		if( !bCaseSensitive )
			sItemText.MakeLower();

		int n;
		while( (n = sItemText.Find( sSearch )) != -1 )
		{
			// Search string found
			if( bWholeWord )
			{
				// Check preceding char
				if( n != 0 )
				{
					if( isalpha(sItemText[n-1]) || 
					    	sItemText[n-1] == '_' ){
						// Not whole word
						sItemText = sItemText.Right(
							sItemText.GetLength() - n - 
							lenSearchStr );
						continue;
					}
				}

				// Check succeeding char
				if( sItemText.GetLength() > n + lenSearchStr
					&& ( isalpha(sItemText[n+lenSearchStr]) ||
					sItemText[n+lenSearchStr] == '_' ) )
				{
					// Not whole word
					sItemText = sItemText.Right( sItemText.GetLength() 
							- n - sSearch.GetLength() );
					continue;
				}
			}
			
			if( IsFindValid( htiCur ) )
				return htiCur;
			else break;
		}


		htiCur = bDownDir ? GetNextItem( htiCur ) : GetPrevItem( htiCur );
		if( htiCur == NULL )
		{
			if( bDownDir )  htiCur = m_pTreeCtrl->GetRootItem();
			else htiCur = GetLastItem( NULL );
		}
	}
	return NULL;
}

// IsFindValid	- Virtual function used by FindItem to allow this
//		  function to filter the result of FindItem
// Returns	- True if item matches the criteria
// Arg		- Handle of the item
BOOL CFolderView::IsFindValid( HTREEITEM )
{
	return TRUE;
}

void CFolderView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	
	*pResult = 0;
}

void CFolderView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// do nothing
	*pResult = 0;
	
}

void CFolderView::UpdateTree()
{
	CmdbViewerDoc* pDoc =GetDocument();
	m_pTreeCtrl->DeleteAllItems( );
	// midfy the parent items
	m_htiDatabase = m_pTreeCtrl->InsertItem(pDoc->m_strDatabasePath, 0, 0 );
	m_pTreeCtrl->SetItemState( m_htiDatabase, TVIS_BOLD, TVIS_BOLD );
	
	// add childeren items
	for (int i=0; i<pDoc->GetTableNumber(); i++)
	{
		m_pTreeCtrl->InsertItem( pDoc->GetTableName(i), 1, 2, m_htiDatabase );
	}

	m_pTreeCtrl->Expand(m_htiDatabase, TVE_EXPAND);
}



void CFolderView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// Get the pointer of GetmdbViewerView() from CMainFrame.
	CmdbViewerView* pView =
		((CMainFrame*)AfxGetMainWnd())->GetmdbViewerView();
	CmdbViewerDoc* pDoc =GetDocument();
	
	HTREEITEM hti = m_pTreeCtrl->GetSelectedItem();
	
	if (hti)
	{
		HTREEITEM htiP=m_pTreeCtrl->GetParentItem(hti);
		// if the hited item's parent is the data base, it
		// must be a table item, open it then.
		if(htiP==m_htiDatabase) {
			// set table name first
			pDoc->SetTableName(m_pTreeCtrl->GetItemText (hti));
			// open this table then
			pView->ShowDBTable();
		}
	}
	*pResult = 0;
}